﻿// main.cpp —— 线程池压力测试（基于 ArrayBlockingQueue）
#include "ThreadPool.h"
#include <iostream>
#include <chrono>
#include <future>
#include <atomic>
#include <stdexcept>

// 模拟一个有计算开销的任务
int mockTask(int id, int work = 500) {
    int sum = 0;
    for (int i = 0; i < work; ++i) {
        sum += (id + i) % 100;
    }
    // 可以取消下面这行的注释，模拟偶尔延迟（调试用）
     //if (id % 1000 == 0) std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    return sum;
}

int main() {
    using namespace std::chrono;

    // ========== 用户可配置参数 ==========
    const size_t TASK_COUNT = 150000;        // 总任务数，比如 1万、10万、100万
    const size_t QUEUE_CAPACITY = 10000;       // ArrayBlockingQueue 容量
    const size_t CORE_POOL_SIZE = 50;         // 核心线程数
    const size_t MAX_POOL_SIZE = 150;          // 最大线程数
    const microseconds KEEP_ALIVE_TIME(10*1000*1000);// 空闲线程存活时间（微秒）

    // 拒绝策略：Abort（异常）、Discard（丢弃）、DiscardOldest（丢弃最老）、CallerRuns（调用者执行）
    const RejectPolicy REJECT_POLICY = RejectPolicy::CallerRuns; // 可换为 Abort / Discard / DiscardOldest

    std::cout << "==================================================\n";
    std::cout << "🚀 线程池压力测试启动\n";
    std::cout << "🏗️  配置信息:\n";
    std::cout << "   • 核心线程数     : " << CORE_POOL_SIZE << "\n";
    std::cout << "   • 最大线程数     : " << MAX_POOL_SIZE << "\n";
    std::cout << "   • 队列类型       : ArrayBlockingQueue\n";
    std::cout << "   • 队列容量       : " << QUEUE_CAPACITY << "\n";
    std::cout << "   • 拒绝策略       : ";
    switch (REJECT_POLICY) {
    case RejectPolicy::Abort: std::cout << "Abort（队列满抛异常）"; break;
    case RejectPolicy::Discard: std::cout << "Discard（队列满静默丢弃）"; break;
    case RejectPolicy::DiscardOldest: std::cout << "DiscardOldest（队列满丢弃最老任务）"; break;
    case RejectPolicy::CallerRuns: std::cout << "CallerRuns（队列满时由提交者线程执行）"; break;
    }
    std::cout << "\n";
    std::cout << "   • 总任务数       : " << TASK_COUNT << "\n";
    std::cout << "==================================================\n";

    // ========== 创建线程池 ==========
    auto queue = std::make_unique<ArrayBlockingQueue>(QUEUE_CAPACITY,REJECT_POLICY);
    ThreadPool pool(
        CORE_POOL_SIZE,
        MAX_POOL_SIZE,
        std::chrono::microseconds(KEEP_ALIVE_TIME),
        std::move(queue)
    );

	std::this_thread::sleep_for(std::chrono::seconds(5)); // 等待线程池初始化

    std::atomic<size_t> success{ 0 };
    std::atomic<size_t> fail{ 0 };

    // ========== 提交任务 ==========
    auto start = high_resolution_clock::now();

    for (size_t i = 0; i < TASK_COUNT; ++i) {
        try {
            // 提交任务，获取 future
            auto future = pool.enqueue([i]() {
                return mockTask(i, 100000); // 可控制任务计算量
                });

            // 获取任务执行结果，统计成功/失败
            //try {
            //    future.get(); // 阻塞直到任务完成，可抛出任务内异常
            //    success++;
            //}
            //catch (const std::exception& ex) {
            //    std::cerr << "[失败] 任务 " << i << " 执行异常: " << ex.what() << "\n";
            //    fail++;
            //}

        }
        catch (const std::exception& ex) {
            // 比如 Abort 策略下，队列满时 enqueue() 可能抛异常
            std::cerr << "[失败] 任务 " << i << " 提交失败: " << ex.what() << "\n";
            fail++;
        }
    }

    auto end = high_resolution_clock::now();
    duration<double> elapsed = end - start;

    // ========== 输出测试结果 ==========
    std::cout << "\n✅ 压力测试完成\n";
    std::cout << "⏱️  总耗时: " << elapsed.count() << " 秒\n";
    std::cout << "📊 成功任务数: " << success << "\n";
    std::cout << "❌ 失败任务数: " << fail << "\n";
    std::cout << "🎯 总任务数: " << TASK_COUNT << "\n";
    std::cout << "📈 吞吐量: " << (success / elapsed.count()) << " 任务/秒\n";
    std::cout << "📉 平均延迟: "
        << (elapsed.count() * 1000000 / std::max<size_t>(1, success))
        << " 微秒/任务\n";
	system("pause");
    return 0;
}